package com.hqd.ch03.v35.web.servlet.mvc.method.annotation;

import com.hqd.ch03.v35.core.MethodParameter;
import com.hqd.ch03.v35.web.context.request.NativeWebRequest;
import com.hqd.ch03.v35.web.method.support.HandlerMethodArgumentResolver;
import com.hqd.ch03.v35.web.method.support.HandlerMethodReturnValueHandler;
import com.hqd.ch03.v35.web.servlet.support.ModelAndViewContainer;

import java.util.Map;

public class MapMethodProcessor implements HandlerMethodArgumentResolver, HandlerMethodReturnValueHandler {

    @Override
    public boolean supportsParameter(MethodParameter parameter) {
        return (Map.class.isAssignableFrom(parameter.getParameterType()) &&
                parameter.getParameterAnnotations().length == 0);
    }

    @Override
    public Object resolveArgument(MethodParameter parameter, ModelAndViewContainer mavContainer,
                                  NativeWebRequest webRequest) throws Exception {

        return mavContainer.getModel();
    }

    @Override
    public boolean supportsReturnType(MethodParameter returnType) {
        return Map.class.isAssignableFrom(returnType.getParameterType());
    }

    @Override
    @SuppressWarnings({"rawtypes", "unchecked"})
    public void handleReturnValue(Object returnValue, MethodParameter returnType,
                                  ModelAndViewContainer mavContainer, NativeWebRequest webRequest) throws Exception {

        if (returnValue instanceof Map) {
            mavContainer.addAllAttributes((Map) returnValue);
        } else if (returnValue != null) {
            throw new UnsupportedOperationException("Unexpected return type [" +
                    returnType.getParameterType().getName() + "] in method: " + returnType.getMethod());
        }
    }

}
